#include <iostream>
#include <unistd.h>
#include <libpmemobj++/container/concurrent_hash_map.hpp>
#include <libpmemobj++/container/string.hpp>
#include <libpmemobj++/p.hpp>
#include <libpmemobj++/persistent_ptr.hpp>
#include <libpmemobj++/pool.hpp>
#include <string>
#include <vector>

/*******************************************
竟然不支持map<string, int>?????????????
*****************************************8**/

const int POOLSIZE = 1024 * 1024 * 64;

using hashmap_type =
	pmem::obj::concurrent_hash_map<pmem::obj::p<int>, pmem::obj::p<int>>;



struct root {
	pmem::obj::persistent_ptr<hashmap_type> pptr = nullptr;
};

static inline int file_exists(char const *file) {
    return access(file, F_OK);
}

int main(int argc, char *argv[]) {

    pmem::obj::pool<root> pop;
    const char * path = "dst_file";
    if (file_exists(path) != 0) {
        pop = pmem::obj::pool<root>::create(path, "string_example", PMEMOBJ_MIN_POOL);
    } else {
        pop = pmem::obj::pool<root>::open(path, "string_example");
    }

	auto &r = pop.root()->pptr;

    if (r == nullptr) {
        pmem::obj::transaction::run(pop, [&] {
            r = pmem::obj::make_persistent<hashmap_type>();
        });
        r->runtime_initialize();
    } else {
        r->runtime_initialize();
        r->defragment();
    }

	auto &map = *r;
	std::cout << " Number of elements at application startup: " << map.size() << std::endl;
		
    for (int i = 0; i < 30; ++i) {
        map.insert_or_assign(i, i+1);
    }

    for (int j = 0; j < 30; ++j) {
        hashmap_type::const_accessor acc;
        bool res = map.find(acc, j);

        if (res) {
            assert(acc->first == j);
            const pmem::obj::p<int> *element = &acc->second;
            std::cout << *element << std::endl;
        }

    }
    map.defragment();
    pop.close();

}
